// Ofri Keidar 302933981 group 05

package model.database;

import java.util.List;
import java.util.Map;

import model.CommonValues;

/**
 * Database for store's data- saves employees, customers, products, orders and user names. 
 * Can answer queries and return the relevant information
 */
public interface Database {

	/**
	 * Gets employee details and adds an employee to store database.
	 * New employee's type if defined by the permission.
	 * Default user name is employee's number, and password is set to default password.
	 * Cannot add employee if there is another employee record with given number
	 * @param number- new employee's number
	 * @param name- new employee's name
	 * @param userName- new employee's user-name
	 * @param permission- new emploee's permission
	 * @return True if could add a new employee with given details, False if not
	 * @throws DBException if had errors connecting to database
	 */
	public boolean addEmployee(int number, String name, String userName,
			CommonValues.permissions permission) throws DBException;
	
	/**
	 * Creates a new account for customer matching given details.
	 * A new user-name record is created- default user name is customer's number.
	 * Cannot add customer if there is another customer record with given number
	 * @param number- new cutomer's number
	 * @param name- new cutomer's name
	 * @param address- new cutomer's address 
	 * @param userName- new customer's user-name
	 * @param paymentMethod- new cutomer's payment method
	 * @return True if could create customer account, False if not
	 * @throws DBException if had problems connecting to database
	 */
	public boolean createCustomerAccount(int number, String name, String userName,
			String address, CommonValues.paymentMethods paymentMethod)
			throws DBException;
	
	/**
	 * Adds a new record with given user-name, permission and default password.
	 * Cannot add user if there is another user record with given user-name, password and permission
	 * @param userName- user-name for the new record
	 * @param permission- permission for the new record
	 * @return True if could add a new user-name record, False if not
	 * @throws DBException if had errors connecting to database
	 */
	public boolean addUserRecord(String userName,
			CommonValues.permissions permission) throws DBException;

	/**
	 * Adds a new product with given name and price.
	 * Cannot add product if there is another product record with given name
	 * @param name- new product's name
	 * @param price- new product's price
	 * @return True if could add product, False if not
	 * @throws DBException if had problems connecting to database
	 */
	public boolean addNewProduct(String name, double price) throws DBException;

	/**
	 * Adds a new order with given details. 
	 * Order's date is set to be current date.
	 * Cannot add order if there is another order record with given number,
	 * or if there is no product matching given name or no customer matching
	 * given number	 
	 * @param orderNumber- new order's number
	 * @param productName- name of product to order
	 * @param amount- how many items to order
	 * @param customerNumber- number of ordering customer
	 * @return True if could add order, False if not
	 * @throws DBException if had problems connecting to database
	 */
	public boolean addNewOrder(int orderNumber, String productName, int amount,
			int customerNumber) throws DBException;

	/**
	 * Updates price of product with given name to given price.
	 * If there is no product with given name, returns False and
	 * no price is updated
	 * @param name- product to update's name
	 * @param newPrice- new price to set
	 * @return True if could update price, False if not
	 * @throws DBException if had problems connecting database
	 */
	public boolean updateProductPrice(String name, double newPrice)
			throws DBException;

	/**
	 * Sets given details for customer matching given number.
	 * If there is no customer with given number, False is returned
	 * and no details are updated
	 * @param number- number of customer to update
	 * @param name- new name for customer
	 * @param address- new address for customer
	 * @param paymentMethod- new payment method for customer
	 * @return True if could update customer's details, False if not
	 * @throws DBException if had problems connecting database
	 */
	public boolean updateCustomerDetails(int number, String name, String address,
			CommonValues.paymentMethods paymentMethod) throws DBException;

	/**
	 * Sets given password to given user. Password is set only if
	 * correct (old) password is given
	 * @param userName- user to change the password to
	 * @param oldPassword- user's old password
	 * @param newPassword- password to set
	 * @return True if could set password, False if not
	 * @throws DBException if had problems connecting to database
	 */
	public boolean setPassword(String userName, String oldPassword, String newPassword)
			throws DBException;
	
	/**
	 * Returns all products- name and price
	 * @return List where each element is a map of product's parameters
	 * @throws DBException if had problems connecting database 
	 */
	public List<Map<String, String>> getProducts() throws DBException;

	/**
	 * Returns price of the product with given name
	 * @param productName- product's name to check
	 * @return product's name
	 * @throws DBException if had problems connecting to database,
	 * 					   or if product does not exists, 
	 * 					   or value stored as product's price is not 
	 * 					   a numeric value 
	 */
	public double getProductPrice(String productName) throws DBException;

	/**
	 * Returns all employees
	 * @return List where each element is a map of product's parameters
	 * @throws DBException if had problems connecting to database 
	 */
	public List<Map<String, String>> getEmployees() throws DBException;

	/**
	 * Returns all customers
	 * @return List where each element is a map of product's parameters
	 * @throws DBException if had problems connecting to database 
	 */
	public List<Map<String, String>> getCustomers() throws DBException;

	/**
	 * Returns all customers that have ordered product matching given
	 * product name
	 * @return List where each element is a map of customer's parameters
	 * @throws DBException if had problems connecting to database 
	 */
	public List<Map<String, String>> getCustomers(String productName)
			throws DBException;

	/**
	 * Returns all customers that have ordered products in worth greater than
	 * given value
	 * @param totalSum- lower bound for order's worth
	 * @return List where each element is a map of customer's parameters
	 * @throws DBException if had problems connecting to database
	 */
	public List<Map<String, String>> getCustomers(double totalSum)
			throws DBException;

	/**
	 * Returns orders made by customer matching given number
	 * @param customerNumber- customer number whose orders to search
	 * @return List where each element is a map of order's parameters
	 * @throws DBException if had problems connecting to database
	 */
	public List<Map<String, String>> getOrders(int customerNumber)
			throws DBException;

	/**
	 * Returns total sum of orders made on given date
	 * @param date- date to check, must be a string in format: "yyyy-mm-dd"
	 * @return total sum of orders made on given date
	 * @throws DBException if had problems connecting to database
	 */
	public double getSalesReport(String date) throws DBException;

	/**
	 * Returns total sum of orders made on given month
	 * @param date- month to check
	 * @return total sum of orders made on given month
	 * @throws DBException if had problems connecting to database
	 */
	public double getSalesReport(int month) throws DBException;
	
	/**
	 * Returns all user-names matching given permission
	 * @param permission- permission to search
	 * @return list of all user-names matching given permission
	 * @throws DBException if had problems connecting to database
	 */
	
	/**
	 * Returns permissions of all employees in system
	 * @return list holding each employee permission
	 * @throws DBException if had problems connecting to database
	 */
	public List<CommonValues.permissions> getEmployeesPermissions()
			throws DBException;
}